package com.imflea.zero.utils;

import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.util.StringUtils;

@Slf4j
public class HighLevelClientUtils {


    /**
     * 更新文档
     *
     * @param restHighLevelClient 客户端
     * @param indexName           索引名
     * @param targetVo            date
     * @return
     */
    public static boolean updateDoc(RestHighLevelClient restHighLevelClient, String indexName, Object targetVo, String id) {
        try {
            if (targetVo != null && !StringUtils.isEmpty(id)) {
                GetRequest getRequest = new GetRequest(indexName, id);
                boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
                String json = JSONUtil.parse(targetVo, JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss")).toString();
                if (exists) {
                    // 存在更新

                    UpdateRequest updateRequest = new UpdateRequest(indexName, id).doc(json, XContentType.JSON);
                    UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
                    log.info("[ElasticSearch]updateDocs indexName:{},response:{}", indexName, update);
                } else {
                    // 不存在则添加
                    IndexRequest indexRequest = new IndexRequest(indexName).id(id).source(json, XContentType.JSON);
                    IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
                    log.info("[ElasticSearch]updateDocs indexName:{},response:{}", indexName, index);
                }
                return true;
            }
        } catch (Exception e) {
            log.error("[ElasticSearch]updateDoc，indexName={}", indexName, e);
        }
        return false;
    }


    /**
     * 删除文档
     *
     * @param restHighLevelClient 客户端
     * @param indexName           索引名
     * @param id                  id
     * @return
     */
    public static boolean deleteDoc(RestHighLevelClient restHighLevelClient, String indexName, String id) {
        try {
            DeleteRequest deleteRequest = new DeleteRequest(indexName);
            deleteRequest.id(id);
            DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
            log.info("[ElasticSearch]deleteDoc indexName:{},response:{}", indexName, response);
            return true;
        } catch (Exception e) {
            log.error("[ElasticSearch]deleteDoc，indexName={}", indexName, e);
        }
        return false;
    }


    public static boolean deleteByQuery(RestHighLevelClient restHighLevelClient, String indexName, QueryBuilder query) {

        DeleteByQueryRequest deleteRequest = new DeleteByQueryRequest(indexName);

        deleteRequest.setQuery(query);
        try {
            BulkByScrollResponse response = restHighLevelClient.deleteByQuery(deleteRequest, RequestOptions.DEFAULT);

            return true;
        } catch (Exception e) {
            log.error("[ElasticSearch]deleteDoc，indexName={}", indexName, e);
        }
        return false;
    }


    /**
     * 搜索
     *
     * @param restHighLevelClient 客户端
     * @param indexName           索引名
     * @param searchSourceBuilder 条件
     * @return
     */
    public static SearchResponse search(RestHighLevelClient restHighLevelClient, String indexName, SearchSourceBuilder searchSourceBuilder) {
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices(indexName);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            return searchResponse;
        } catch (Exception e) {
            log.error("[ElasticSearch]search", e);
        }
        return null;
    }

}


